﻿using IdentityServer4.Events;
using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Stores;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RequestLocalization;
using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.Threading.Tasks;
using ERP.Abp.Account.Settings;
using ERP.Abp.Account.Web;
using ERP.Abp.Account.Web.Pages.Account;
using Volo.Abp.DependencyInjection;
using ERP.Abp.Identity;
using ERP.Abp.Identity.AspNetCore;
using ERP.Abp.SettingManagement;
using Volo.Abp.Settings;

namespace ERP.Pages.Account
{
  // [ExposeServices(typeof(IdentityServerSupportedLoginModel))]
    public class  MyLoginModel : ERP.Abp.Account.Web.Pages.Account.IdentityServerSupportedLoginModel,ITransientDependency
    {
        ISettingManager _settingManager;
        public MyLoginModel(IAuthenticationSchemeProvider schemeProvider, IOptions<AbpAccountOptions> accountOptions, IIdentityServerInteractionService interaction, IClientStore clientStore, IEventService identityServerEvents, IOptions<IdentityOptions> identityOptions,
            ISettingManager settingManager
            ) : base(schemeProvider, accountOptions, interaction, clientStore, identityServerEvents, identityOptions)
        {
            _settingManager=settingManager;
           
        }
        public override async Task<IActionResult> OnPostAsync(string action)
        {
            var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);
            if (action == "Cancel")
            {
                if (context == null)
                {
                    return Redirect("~/");
                }

                await Interaction.GrantConsentAsync(context, new ConsentResponse()
                {
                    Error = AuthorizationError.AccessDenied
                });

                return Redirect(ReturnUrl);
            }

            await CheckLocalLoginAsync();

            ValidateModel();

            await IdentityOptions.SetAsync();

            ExternalProviders = await GetExternalProviders();

            EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);

            await ReplaceEmailToUsernameOfInputIfNeeds();

            var result = await SignInManager.PasswordSignInAsync(
                LoginInput.UserNameOrEmailAddress,
                LoginInput.Password,
                LoginInput.RememberMe,
                true
            );

            await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
            {
                Identity = IdentitySecurityLogIdentityConsts.Identity,
                Action = result.ToIdentitySecurityLogAction(),
                UserName = LoginInput.UserNameOrEmailAddress,
                ClientId = context?.Client?.ClientId
            });

            if (result.RequiresTwoFactor)
            {
                return await TwoFactorLoginResultAsync();
            }

            if (result.IsLockedOut)
            {
                Alerts.Warning(L["UserLockedOutMessage"]);
                return Page();
            }

            if (result.IsNotAllowed)
            {
                Alerts.Warning(L["LoginIsNotAllowed"]);
                return Page();
            }

            if (!result.Succeeded)
            {
                Alerts.Danger(L["InvalidUserNameOrPassword"]);
                return Page();
            }

            //TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
            var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
                       await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);

            Debug.Assert(user != null, nameof(user) + " != null");
            await IdentityServerEvents.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName)); //TODO: Use user's name once implemented

            //  return RedirectSafely(ReturnUrl, ReturnUrlHash);

            return Redirect(ReturnUrl);

        }
        public override Task<IActionResult> OnGetAsync()
        {
            SetDefaultCulture();
           
            return base.OnGetAsync();
        }

        //设置默认语言
        public   void SetDefaultCulture()
        {
            if (!HttpContext.Request.Cookies.ContainsKey(CookieRequestCultureProvider.DefaultCookieName))
            {
                AbpRequestCultureCookieHelper.SetCultureCookie(
            HttpContext,
         new RequestCulture("zh-Hans", "zh-Hans"));
              

            }
        }
    }
}
  